import CryptoJs from "crypto-js";
import { getUrlAndEncData } from "./index";
const base64 = require('js-base64')
const encData = getUrlAndEncData().encData;

const aesKey = base64.decode(encData.aesKey.substr(8, encData.aesKey.length - 16))

function hash(kqDY1: string, SkO2: string): string {
    return CryptoJS.HmacSHA256(
        kqDY1 + SkO2,
        aesKey
    ).toString();
}

function validPayload(Xbcii$F3: any): boolean {
    return (typeof Xbcii$F3 === "object" &&
        "iv" in Xbcii$F3 &&
        "mac" in Xbcii$F3 &&
        "value" in Xbcii$F3 &&
        CryptoJS.enc.Base64.parse(Xbcii$F3.iv).sigBytes === 16);
}

function random(): string {
    return Math.random().toString(36).substr(2);
}

function randomBytes(): CryptoJs.lib.WordArray {
    return CryptoJS.enc.Utf8.parse(
        CryptoJS.MD5(random()).toString().substr(9, 16)
    );
}

function calculateMac(iyrmEa4: any, RDX5: any): CryptoJs.lib.WordArray {
    return CryptoJS.HmacSHA256(
        hash(iyrmEa4.iv, iyrmEa4.value),
        RDX5
    );
}

function hashEquals(UScFcLEp6: CryptoJs.lib.WordArray, Dlrevd7: CryptoJs.lib.WordArray): boolean {
    const uscStr = UScFcLEp6.toString();
    const dlrStr = Dlrevd7.toString();
    const len = uscStr.length;
    let result = 0;
    for (let i = 0; i < len; ++i) {
        result |=
            uscStr.charCodeAt(i) ^
            dlrStr.charCodeAt(i);
    }
    return result === 0;
}

function validMac(a: any) {
    const bytes = randomBytes();
    const calculated = calculateMac(a, bytes);
    return hashEquals(CryptoJS.HmacSHA256(a.mac, bytes), calculated);
}



function getJsonPayload(aEAbEUasi8: string): any {
    aEAbEUasi8 = CryptoJS.enc.Base64.parse(aEAbEUasi8).toString(CryptoJS.enc.Utf8);
    const aEAbEUasi8WA: CryptoJs.lib.WordArray = JSON.parse(aEAbEUasi8);
    if (!validPayload(aEAbEUasi8WA)) {
        throw new window.Error("The payload is invalid.");
    }
    if (!validMac(aEAbEUasi8WA)) {
        throw new window.Error("The MAC is invalid.");
    }
    return aEAbEUasi8WA;
}


export function aesEncrypt(imb9: unknown): string {
    const key = CryptoJS.enc.Utf8.parse(aesKey);
    const iv = randomBytes();
    const param = {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    };
    const plaintext = JSON.stringify(imb9);
    const ciphertext = CryptoJS.AES.encrypt(plaintext, key, param).toString();
    const ivStr = CryptoJS.enc.Base64.stringify(iv).toString();
    const mac = hash(
        ivStr,
        ciphertext
    );
    const json = JSON.stringify({
        iv: ivStr,
        mac: mac,
        value: ciphertext
    });
    return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(json));
}

export function aesDecrypt(HTrZAqKQ10: string): any {
    const payload = getJsonPayload(HTrZAqKQ10);
    const key = CryptoJS.enc.Utf8.parse(aesKey);
    const iv = CryptoJS.enc.Base64.parse(payload.iv);
    const param = {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    };
    const plaintext = CryptoJS.AES.decrypt(
        payload.value,
        key,
        param
    );
    return JSON.parse(plaintext.toString(CryptoJS.enc.Utf8));
}